package com.ftwj.demo.config.solr;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.client.HttpClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.ftwj.demo.utils.StringHelper;
import com.ftwj.demo.utils.logs.LoggerUtil;

import cn.hutool.core.bean.BeanUtil;

@Component
public class SolrUtil<T> {
	
	private final static Logger logger = LoggerFactory.getLogger(SolrUtil.class);

	@Autowired
	private HttpSolrClient client;
	
	public HttpClient load() {
		HttpClient  httpClient = client.getHttpClient();
		LoggerUtil.info(httpClient.toString());
		return httpClient;
	}
	
	/**
	 * @Title: addMap
	 * @Description: 根据Map添加索引
	 * @author: WangShengLi
	 * @param map
	 * @return: boolean
	 */
	public boolean addMap(Map<String,Object> map){
		SolrInputDocument doc = new SolrInputDocument();
		for(Entry<String, Object> entry:map.entrySet()){
			String key=entry.getKey();
			Object value=entry.getValue();
			if(value != null) {
				doc.addField(key, value);
			}
		}
		try {
			client.add(doc);
			UpdateResponse resp = client.commit();
			if(resp.getStatus() == 0) {
				return true;
			}
		} catch(Exception e)
		{
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * @Title: addBean
	 * @Description: 根据实体添加索引
	 * @author: WangShengLi
	 * @param bean
	 * @throws SolrServerException
	 * @throws IOException
	 * @return: boolean
	 */
	public boolean addBean(T bean) throws SolrServerException, IOException {
		try {
			client.addBean(bean);
			UpdateResponse res = client.commit();
			if(res.getStatus() == 0) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();//Cannot retry request with a non-repeatable request entity. 发生链接异常
		}
		return false;
	}
	
	/**
	 * @Title: addBeans
	 * @Description: 根据实体集合添加索引
	 * @author: WangShengLi
	 * @param beans
	 * @throws SolrServerException
	 * @throws IOException
	 * @return: boolean
	 */
	public boolean addBeans(Collection<?> beans) throws SolrServerException, IOException {
		try {
			client.addBeans(beans);
			UpdateResponse res = client.commit();
			if(res.getStatus() == 0) {
				return true;
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return false;
			
	}
	
	/**
	 * @Title: deleteById
	 * @Description: 根据Id删除索引
	 * @author: WangShengLi
	 * @param id
	 * @return: boolean
	 */
	public boolean deleteById(String id) {
		try {
			client.deleteById(id);
			UpdateResponse resp = client.commit();
			if(resp.getStatus() == 0) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * @Title: deleteByQuery
	 * @Description: 根据查询条件删除索引
	 * @author: WangShengLi
	 * @param query
	 * @return: boolean
	 */
	public boolean deleteByQuery(String query) {
		try {
			client.deleteByQuery(query);
			UpdateResponse resp = client.commit();
			if (resp.getStatus() == 0) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * @Title: updateMap
	 * @Description: 更新Solr中的文档，Map对象中必须存在id键用于定位doc文档Map中其他的键值对是修改的内容
	 * 	Key<String>代表数据域名称, Value<Object>代表修改值
	 * @author: WangShengLi
	 * @param map
	 * @return: boolean
	 */
	public boolean updateMap(Map<String, Object> map) {
		SolrInputDocument doc = new SolrInputDocument();
		for (Entry<String, Object> entry: map.entrySet()) {
			String key=entry.getKey();
			Object value=entry.getValue();
			if(value != null) {
				doc.addField(key, value);
			}
		}
		try {	
			client.add(doc);
			UpdateResponse resp = client.commit();
			if (resp.getStatus() == 0) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 
	 * @Title: updateBean
	 * @Description: 根据实体修改
	 * @author: WangShengLi
	 * @param bean
	 * @return
	 * @return: boolean
	 */
	public boolean updateBean(T bean) {
		try {
			client.addBean(bean);
			UpdateResponse res = client.commit();
			if(res.getStatus() == 0) {
				return true;
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		} 
		return false;
	}

	/**
	 * @Title: query
	 * @Description: 查询全部
	 * @author: WangShengLi
	 * @return: List<Map>
	 */
	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> query() {
		List<Map<String, Object>> list = new ArrayList<>();
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery("*:*");
		try {
			QueryResponse queryResponse = client.query(solrQuery);
			if (queryResponse != null) {
				SolrDocumentList solrDocumentList = queryResponse.getResults();
				for(SolrDocument solrDocument:solrDocumentList) {
					Map<String, Object> map = solrDocument.toMap(new HashMap<String,Object>());
					list.add(map);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	/**
	 * @Title: query
	 * @Description: 查询全部,带高亮字段
	 * @author: WangShengLi
	 * @param resultType
	 * @return: List<Map<String, Object>>
	 */
	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> query(String query,String[] highlights,int rows) throws Exception {
		List<Map<String, Object>> resultList = new ArrayList<>();
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery("*:*");
		if(StringHelper.isNotEmpty(query)) {
			solrQuery.setQuery(query);
		}
		solrQuery.setRows(rows);
		//solrQuery.set("fl", "*"); //返回的字段，默认全部
		//solrQuery.set("df", "words"); //默认搜索的字段
		// 高亮显示
		if(highlights!=null&&highlights.length>0) {
			solrQuery.setHighlight(true);
			// 设置高亮显示的域
			for(String highlight:highlights) {
				solrQuery.addHighlightField(highlight);
			}
			// 高亮显示前缀
			solrQuery.setHighlightSimplePre("<font color='red'>");
			// 后缀
			solrQuery.setHighlightSimplePost("</font>");
		}
		try {
			QueryResponse queryResponse = client.query(solrQuery);
			if (queryResponse == null) {
				return null;
			}
			SolrDocumentList solrDocumentList = queryResponse.getResults();
			if (solrDocumentList.isEmpty()) {
				return null;
			}
			// 获取高亮
			Map<String, Map<String, List<String>>> highLightmap = queryResponse.getHighlighting();
			for (SolrDocument solrDocument : solrDocumentList) {
				for(String highlight:highlights) {
					List<String> list = highLightmap.get(solrDocument.get("id")).get(highlight);
					System.err.println(list);
					if (!CollectionUtils.isEmpty(list)) {
						solrDocument.setField(highlight, list.get(0));
					}
				}
				Map<String, Object> map = solrDocument.toMap(new HashMap<String,Object>());
				resultList.add(map);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultList;
	}
	
	/**
	 * @Title: query
	 * @Description: 不分页查询全部
	 * @author: WangShengLi
	 * @param resultType
	 * @return: List<T>
	 */
	public List<T> query(Class<T> resultType) {
		List<T> list = new ArrayList<>();
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery("*:*");
		try {
			QueryResponse queryResponse = client.query(solrQuery);
			if (queryResponse != null) {
				list = queryResponse.getBeans(resultType);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	/**
	 * @Title: query
	 * @Description: 根据solr条件查询 带高亮，排序
	 * @author: WangShengLi
	 * @param query
	 * @param resultType 
	 * @param highlights 要高亮显示的字段，null则不高亮显示
	 * @param rows 总条数
	 * @throws Exception
	 * @return: List<T>
	 */
	public List<T> query(String query,Class<T> resultType,String[] highlights,int rows,Map<String,SolrQuery.ORDER> orderMap) throws Exception {
   		T bean = resultType.newInstance();
		List<T> resultList = new ArrayList<>();
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery("*:*");
		if(StringHelper.isNotEmpty(query)) {
			solrQuery.setQuery(query);
		}
		solrQuery.setRows(rows);
		for (Entry<String, SolrQuery.ORDER> entry : orderMap.entrySet()) {
			solrQuery.addSort(entry.getKey(),entry.getValue());
		}
		//返回值字段
		//solrQuery.set("fl", "*");
		// 设置默认搜索的域
		//solrQuery.set("df", "words");
		if(highlights!=null&&highlights.length>0) {
			solrQuery.setHighlight(true);
			// 设置高亮显示的域
			for(String highlight:highlights) {
				solrQuery.addHighlightField(highlight);
			}
			// 高亮显示前缀
			solrQuery.setHighlightSimplePre("<font color='red'>");
			// 后缀
			solrQuery.setHighlightSimplePost("</font>");
		}
		try {
			QueryResponse queryResponse = client.query(solrQuery);
			if (queryResponse == null) {
				return null;
			}
			SolrDocumentList solrDocumentList = queryResponse.getResults();
			if (solrDocumentList.isEmpty()) {
				return null;
			}
			// 获取高亮
			Map<String, Map<String, List<String>>> map = queryResponse.getHighlighting();
			for (SolrDocument solrDocument : solrDocumentList) {
				for(String highlight:highlights) {
					List<String> list = map.get(solrDocument.get("id")).get(highlight);
					if (!CollectionUtils.isEmpty(list)) {
						solrDocument.setField(highlight, list.get(0));
					}
				}
				bean=BeanUtil.toBean(solrDocument, resultType);
				resultList.add(bean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return resultList;
	}
	
	/**
	 * 
	 * @Title: page
	 * @Description: 分页显示查询结果 带高亮，分页，排序
	 * @author: WangShengLi
	 * @param query
	 * @param resultType
	 * @param highlights
	 * @param page 当前页
	 * @param limit 每页条数
	 * @throws Exception
	 * @return: PageInfoBean
	 */
	public PageInfoBean page(String query,Class<T> resultType,String[] highlights,Integer page,Integer limit,Map<String,SolrQuery.ORDER> orderMap) throws Exception {
   		T bean = resultType.newInstance();
   		List<T> resultList = new ArrayList<>();
   		PageInfoBean pageInfo=new PageInfoBean(page,limit);
		SolrQuery solrQuery = new SolrQuery();
		solrQuery.setQuery("*:*");
		if(StringHelper.isNotEmpty(query)) {
			solrQuery.setQuery(query);
		}
		// 设置默认搜索的域
		//solrQuery.set("df", "mykeywords");
		//返回值字段
		//solrQuery.set("fl", "*");
		for (Entry<String, SolrQuery.ORDER> entry : orderMap.entrySet()) {
			solrQuery.addSort(entry.getKey(),entry.getValue());
		}
		pageInfo.calPageParam();
		solrQuery.setStart(pageInfo.getStartIndex());
		solrQuery.setRows(pageInfo.getPerPage());
		if(highlights!=null&&highlights.length>0) {
			solrQuery.setHighlight(true);
			// 设置高亮显示的域
			for(String highlight:highlights) {
				solrQuery.addHighlightField(highlight);
			}
			// 高亮显示前缀
			solrQuery.setHighlightSimplePre("<font color='red'>");
			// 后缀
			solrQuery.setHighlightSimplePost("</font>");
		}
		try {
			QueryResponse queryResponse = client.query(solrQuery);
			if (queryResponse == null) {
				return null;
			}
			SolrDocumentList solrDocumentList = queryResponse.getResults();
			if (solrDocumentList.isEmpty()) {
				return null;
			}
			
			// 获取高亮
			Map<String, Map<String, List<String>>> map = queryResponse.getHighlighting();
			for (SolrDocument solrDocument : solrDocumentList) {
				for(String highlight:highlights) {
					List<String> list = map.get(solrDocument.get("id")).get(highlight);
					if (!CollectionUtils.isEmpty(list)) {
						solrDocument.setField(highlight, list.get(0));
					}
				}
				bean=BeanUtil.toBean(solrDocument, resultType);
				resultList.add(bean);
			}
			pageInfo.setTotalNum(solrDocumentList.getNumFound());
			pageInfo.calPageParam();
			pageInfo.setRecList(resultList);
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return pageInfo;
	}
	
	@SuppressWarnings({ "unchecked", "unused" })
	private Class<T> getGenericityClass(T t) {
		return (Class<T>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
	
}
